﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace Report.Service
{
    public class DomSelector
    {
        private readonly HtmlDocument document;

        public DomSelector(HtmlDocument document)
        {
            this.document = document;
        }

        public HtmlElement Slect(string expression)
        {
            if (string.IsNullOrEmpty(expression)) return null;
            if (expression.IndexOf('=') > -1)
            {
                return SelectById(expression);
            }
            return SelectByExpression(expression);
        }

        private HtmlElement SelectById(string expression)
        {
            string[] nodes = expression.Split('=');
            if ("id".Equals(nodes[0], StringComparison.CurrentCultureIgnoreCase))
            {
                return document.GetElementById(nodes[1]);
            }
            if ("name".Equals(nodes[0], StringComparison.CurrentCultureIgnoreCase))
            {
                return document.GetElementsByTagName(nodes[1])[0];
            }
            return null;
        }

        private HtmlElement SelectByExpression(string expression)
        {
            string[] expressionNodes = expression.Split('/');

            HtmlElement element = null;

            foreach (string node in expressionNodes)
            {
                int a = node.IndexOf('[');
                int b = node.IndexOf(']');
                string nodeName = a > -1 ? node.Substring(0, a) : node;
                int index = a > -1 ? int.Parse(node.Substring(a + 1, b - a - 1)) : 0;

                if (element == null)
                {
                    element = document.GetElementsByTagName(nodeName)[index];
                }
                else
                {
                    int i = 0;
                    bool find = false;
                    foreach (HtmlElement child in element.Children)
                    {
                        if (string.Equals(child.TagName, nodeName, StringComparison.CurrentCultureIgnoreCase))
                        {
                            if (i++ == index)
                            {
                                element = child;
                                find = true;
                                break;
                            }
                        }
                    }
                    if (!find) throw new Exception(expression);
                }
            }
            return element;
        }

        public Rectangle CalculateElementRectangle(HtmlElement element)
        {
            Rectangle rectangle = element.OffsetRectangle;
            while (element.Parent != null)
            {
                if (!"FORM".Equals(element.Parent.TagName, StringComparison.CurrentCultureIgnoreCase))
                {
                    rectangle.X += element.Parent.OffsetRectangle.X;
                    rectangle.Y += element.Parent.OffsetRectangle.Y;
                }
                element = element.Parent;
            }
            return rectangle;
        }
    }
}
